#include "wren_editor_extension.hpp"
#include <fmt/printf.h>
#include <wrenbind17/wrenbind17.hpp>

#include "data/editor_data.hpp"
#include "scripting/scripting_module.h"
#include "wren_base.hpp"
#include "fmt/core.h"

using namespace wrenbind17;

WrenEditorExtension::WrenEditorExtension (IEditorScript::EditorTarget type, std::string title, const std::string &script_path):
    IEditorScript(type, std::move(title), script_path, g_current_module),
    WrenScriptBase(script_path, "Editor")
{
}

WrenEditorExtension::~WrenEditorExtension ()
{
}

void WrenEditorExtension::execute (const void *node)
{
    try {
        auto &vm = WrenShared::SharedVM();
        auto var = vm.find(module_name, "main");
        auto call = var.func("call(_)");
        if (call)
        {
            switch (apply_target_)
            {
            case IEditorScript::eItem: call(static_cast<const ItemNode*>(node)); break;
            case IEditorScript::eDay: call(static_cast<const DayLevelNode*>(node)); break;
            case IEditorScript::eMonth: call(static_cast<const MonthLevelNode*>(node)); break;
            case IEditorScript::eYear: call(static_cast<const YearLevelNode*>(node)); break;
            default: call("Bad Value");
            }
        }
    }
    catch (std::exception &e)
    {
        fprintf(stderr, "Wren run error: %s\n", e.what());
    }
}

IScript* WrenEditorExtension::create (IEditorScript::EditorTarget target, std::string title, const std::string_view &code, const std::string &script_path)
{
    auto extension = new WrenEditorExtension (target, title, script_path);
    if (!extension->compile (code))
    {
        delete extension;
        extension = nullptr;
    }

    return extension;
}

bool WrenEditorExtension::compile (const std::string_view &code) const
{
    try 
    {
        auto &vm = WrenShared::SharedVM();
        auto& m = vm.module(module_name);
        m.append(std::string{ code });
        vm.runFromSource("main", fmt::format("import \"{}\"", module_name));
    }
    catch (std::exception &e)
    {
        fprintf(stderr, "Wren compile error: %s\n", e.what());
        return false;
    }
    return true;
}
